package org.duiduo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import org.duiduo.utils.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.base.Preconditions;
import lombok.extern.slf4j.Slf4j;
import org.duiduo.common.bean.OrderVO;
import org.duiduo.common.dto.OrderDTO;
import org.duiduo.common.request.OrderFindPageRequest;
import org.duiduo.common.response.Page;
import org.duiduo.constant.BaseConstants;
import org.duiduo.constant.ResponseConstants;
import org.duiduo.entity.Book;
import org.duiduo.entity.Order;
import org.duiduo.entity.User;
import org.duiduo.enums.OrderStateEnum;
import org.duiduo.enums.UserRoleEnum;
import org.duiduo.exception.CustomException;
import org.duiduo.mapper.BookMapper;
import org.duiduo.mapper.OrderMapper;
import org.duiduo.mapper.UserMapper;
import org.duiduo.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private BookMapper bookMapper;

    @Resource
    private UserMapper userMapper;

    // 下面是别人的支付参数跳转 这里代码写成假支付宝页面
    /*@Override
    public String buy(Long bookId, User user) {
        Book book = bookMapper.selectById(bookId);
        String orderNo = IdUtil.getSnowflake().nextIdStr();
        String payUrl = "http://localhost:9090/alipay/pay?subject=" + book.getName() + "&traceNo=" + orderNo + "&totalAmount=" + book.getPrice();
        Order order = new Order();
        order.setOrderNo(orderNo);
        order.setTotalPrice(book.getPrice());
        order.setPayPrice(book.getPrice());
        order.setTransportPrice(BigDecimal.ZERO);
        order.setUserId(user.getId());
        order.setUsername(user.getUsername());
        order.setName(book.getName());
        orderMapper.insert(order);
        return payUrl;
    }*/

    /*@Override
    public void updateState(String tradeNo, Integer state, String gmtPayment) {
        orderMapper.updateState(tradeNo, state, gmtPayment);
    }*/

    @Override
    public Order buy(Long bookId, User user) {
        Book book = bookMapper.selectById(bookId);
        // 判断库存
        Preconditions.checkArgument(book.getCount() > 0, ResponseConstants.Resp_2.RESP_01.getMessage());
        // 判断登录用户账户
        Preconditions.checkArgument(user.getAccount().compareTo(book.getPrice()) >= 0, ResponseConstants.Resp_2.RESP_02.getMessage());
        // 查询有没有未支付订单
        LambdaQueryWrapper<Order> wrapper = Wrappers.<Order>lambdaQuery();
        wrapper.eq(Order::getBookId, bookId);
        wrapper.eq(Order::getUserId, user.getId());
        wrapper.eq(Order::getState, OrderStateEnum.NON_PAYMENT.getState());
        Order order = orderMapper.selectOne(wrapper);
        if (order != null) {
            // 存在未支付订单
            order.setBook(book);
            return order;
        }
        // 不存在 未支付订单
        String orderNo = IdUtil.getSnowflake().nextIdStr();
        order = new Order();
        order.setOrderNo(orderNo);
        order.setTotalPrice(book.getPrice());
        order.setPayPrice(book.getPrice());
        order.setTransportPrice(BigDecimal.ZERO);
        order.setUserId(user.getId());
        order.setUsername(user.getUsername());
        order.setCount(1); // 默认购买数量是1
        order.setName(book.getName());
        order.setBookId(book.getId());
        order.setBook(book);
        orderMapper.insert(order);
        // 删除缓存
        redisTemplate.delete(BaseConstants.ORDER_QUERY_KEY + user.getId());
        return order;
    }

    @Override
    public int buySuccess(OrderVO orderVO, User user) {
        // 减库存
        Book book = bookMapper.selectById(orderVO.getBookId());
        try {
            bookMapper.buyAbatementCount(book.getId(), orderVO.getCount());
        } catch (Exception e) {
            log.error("确认支付减库存失败,支付失败:", e);
            // 删除待支付订单
            orderMapper.deleteById(orderVO.getId());
            throw new CustomException(ResponseConstants.Resp_1.RESP_01.getCode(), ResponseConstants.Resp_1.RESP_01.getMessage());
        }
        // 判断登录用户账户
        if (user.getAccount().compareTo(orderVO.getTotalPrice()) < 0) {
            // 删除待支付订单
            orderMapper.deleteById(orderVO.getId());
            throw new CustomException(ResponseConstants.Resp_1.RESP_02.getCode(), ResponseConstants.Resp_1.RESP_02.getMessage());
        }
        // 减账户
        user.setAccount(user.getAccount().subtract(orderVO.getTotalPrice()));
        userMapper.updateById(user);
        // 书籍所属用户账户增加
        User bookOwner = userMapper.selectById(book.getUserId());
        bookOwner.setAccount(bookOwner.getAccount().add(orderVO.getTotalPrice()));
        userMapper.updateById(bookOwner);
        // 支付成功修改订单数据
        Order order = new Order();
        BeanUtil.copyProperties(orderVO, order, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        int count = orderMapper.updateOrderSuccess(order, OrderStateEnum.PAID.getState(), DateUtil.formatDate(new Date(), DateUtil.DATE_FORMAT_1));
        // 删除缓存
        redisTemplate.delete(BaseConstants.ORDER_QUERY_KEY + user.getId());
        return count;
    }

    @Override
    public Page findPage(User user, OrderFindPageRequest request) {
        String str = (String) redisTemplate.opsForValue().get(BaseConstants.ORDER_QUERY_KEY + user.getId());
        if (StrUtil.isNotBlank(str)) {
            return JSON.parseObject(str, Page.class);
        }
        Page page = new Page<>();
        Integer userId = null;
        // 如果是普通用户
        if (UserRoleEnum.NORMAL_USER.getRole().equals(user.getRole())) {
            userId = user.getId();
        }
        request.setUserId(userId);
        List<OrderVO> orderList = orderMapper.findPage(request);
        List<OrderDTO> orderDTOList = new ArrayList<>();
        orderList.forEach(o -> {
            OrderDTO dto = new OrderDTO();
            BeanUtil.copyProperties(o, dto, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            dto.setCreateTime(DateUtil.formatDate(o.getCreateTime(), DateUtil.DATE_FORMAT_1));
            dto.setPayTime(DateUtil.formatDate(o.getPayTime(), DateUtil.DATE_FORMAT_1));
            orderDTOList.add(dto);
        });
        int total = orderMapper.total(request);
        page.setRecords(orderDTOList);
        page.setTotal(total);
        page.setPageNum(request.getPageNum());
        page.setPageSize(request.getPageSize());
        // 存入缓存
        redisTemplate.opsForValue().set(BaseConstants.ORDER_QUERY_KEY + user.getId(), JSON.toJSONString(page), 60L, TimeUnit.SECONDS);
        return page;
    }

    @Override
    public int deleteById(Integer id, User user) {
        int count = orderMapper.deleteById(id);
        // 删除缓存
        redisTemplate.delete(BaseConstants.ORDER_QUERY_KEY + user.getId());
        return count;
    }
}
